/**************************************************************************
 * The reference implementation of the EE122 Project #1
 *
 * Author: Junda Liu (liujd@cs)
 * Author: DK Moon (dkmoon@cs)
 * Author: David Zats (dzats@cs)
**************************************************************************/

#ifndef _protocol_h_
#define _protocol_h_

#include "constants.h"

/* Packs the structure without a hole. __attribute__((pack)) is specific to
   gcc. You can also use #pragma pack(push, 1) to be compatible with
   Microsoft's WIN32 compiler. */
struct ee122_hdr {
  uint8_t version_;
  uint16_t length_;     /* Total message length including the header */
  uint8_t type_;        /* Message type */
  uint8_t payload_[0];
} __attribute__((packed));

struct ee122_login_request {
  char player_name_[EE122_MAX_NAME_LENGTH + 1];
  uint8_t padding_[2];
} __attribute__((packed));

enum {
  LOGIN_REPLY_ERROR_NONE = 0,
  LOGIN_REPLY_ERROR_EXISTING,
};
struct ee122_login_reply {
  uint8_t error_code_;
  int32_t hp_;
  int32_t exp_;
  int8_t x_;
  int8_t y_;
  uint8_t padding_[1];
} __attribute__((packed));

struct ee122_move {
  uint8_t direction_;
  uint8_t padding_[3];
} __attribute__((packed));

struct ee122_move_notify {
  char player_name_[EE122_MAX_NAME_LENGTH + 1];
  int8_t x_;
  int8_t y_;
  int32_t hp_;
  int32_t exp_;
} __attribute__((packed));

struct ee122_attack {
  char victim_name_[EE122_MAX_NAME_LENGTH + 1];
  uint8_t padding_[2];
} __attribute__((packed));

struct ee122_attack_notify {
  char attacker_name_[EE122_MAX_NAME_LENGTH + 1];
  char victim_name_[EE122_MAX_NAME_LENGTH + 1];
  uint8_t damage_;
  int32_t hp_;
  uint8_t padding_[3];
} __attribute__((packed));

struct ee122_speak {
  char msg_[0];
} __attribute__((packed));

struct ee122_speak_notify {
  char broadcaster_name_[EE122_MAX_NAME_LENGTH + 1];
  char msg_[0];
} __attribute__((packed));

struct ee122_logout {
} __attribute__((packed));

struct ee122_logout_notify {
  char player_name_[EE122_MAX_NAME_LENGTH + 1];
  uint8_t padding_[2];
} __attribute__((packed));

enum {
  INVALID_STATE_MUST_LOG_IN = 0,
  INVALID_STATE_ALREADY_LOGGED_IN,
};

struct ee122_invalid_state {
  uint8_t error_code_;
  uint8_t padding_[3];
} __attribute__((packed));

#endif /* _protocol_h_ */
